package InternetHax;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.Sprite;

/**
 * Actors are entities with an inventory, location on the map, and hit points
 * they usually have a sprite, but can be given null to become "invisible" to the player
 * 
 * @author LoginError
 */
public class Actor {

    protected String name = "Error"; //I AM ERROR
    private String spriteFileName ; 
    protected Point2d tilePosition;
    protected Sprite sprite;
    protected int facing;
    protected int HP = 1;
    protected int MaxHP = 100;
    protected boolean destroyMe = false;
    protected int AP = 1;
    protected int APRecovery = 1;

    public void takeDamage(int amount)
    {

    }

    
    public Actor(String name) {
        this.name = name;
    }

    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public void setAP(int ap) {
        this.AP = ap;
    }

    public int getAP() {
        return AP;
    }

    public void gainAP(int gain) {
        AP += gain;
    }

    public void loseAP(int loss) {
        AP -= loss;
    }
    
    public void takeTurn() {
        Toolbox.printDebug("Actor: "+this.name + " is taking a turn:");
    }

    synchronized public void die() {
        if(isHero())
        {
            Gamestate.state = Constants.STATE_GAMEOVER;
        }

        else
        {
            Gamestate.resourceManager.unloadResource(spriteFileName);
            Gamestate.gameManager.removeActor(this);
            Gamestate.theMap.setActorOnTile(null, tilePosition.x, tilePosition.y);
            Gamestate.console.print(getName() + " dies. ");
        }

    }

    public void alterHP(int ammount) {
        setHP(getHP() + ammount);

        if (getHP() >= getMaxHP()) {
            setHP(getMaxHP());
        }
        if (getHP() <= 0) {
            die();
        }
    }

    /**
     * Paints the sprite on the screen
     * @param graphics graphics object on which to paint
     * @param mapOffset where the map is currently being drawn relative to the screen see {@link HaxCanvas} for more info
     * TODO: Comment this better
     */
    public void paint(Graphics graphics, Point2d mapOffset) {
        sprite.setPosition((tilePosition.x * Constants.TILESIZE_IN_PIXELS ) - 
                (mapOffset.x * Constants.TILESIZE_IN_PIXELS) +
                Gamestate.screenWidth / 2 - Constants.TILESIZE_HALF,
                (tilePosition.y * Constants.TILESIZE_IN_PIXELS) - 
                (mapOffset.y * Constants.TILESIZE_IN_PIXELS) +
                Gamestate.screenHeight / 2 - Constants.TILESIZE_HALF);

        sprite.paint(graphics);
    }

    public Actor(Sprite sprite) {
        this.sprite = sprite;
    }

    public boolean canMoveTo(int x, int y) {
        if (Gamestate.theMap.isWalkable(x, y) && !Gamestate.theMap.isThereActorOnTile(x, y)) {
            return true;
        }
        else {
            return false;
        }
    }
    //moved canMove checking here...
    public void move(int direction) {
        switch (direction) {

            case Constants.DIRECTION_UP:
                if (canMoveTo(tilePosition.x, tilePosition.y - 1)) {

                    facing = Constants.DIRECTION_UP;
                    sprite.setFrame(Constants.DIRECTION_UP);
                    Gamestate.theMap.moveActorToTile(this, tilePosition.x, tilePosition.y, tilePosition.x, --tilePosition.y);
                }
            break;

            case Constants.DIRECTION_LEFT:
                if (canMoveTo(tilePosition.x - 1, tilePosition.y)) {

                    facing = Constants.DIRECTION_LEFT;
                    sprite.setFrame(Constants.DIRECTION_LEFT);
                    Gamestate.theMap.moveActorToTile(this, tilePosition.x, tilePosition.y, --tilePosition.x, tilePosition.y);
                }
            break;

            case Constants.DIRECTION_DOWN:
                if (canMoveTo(tilePosition.x, tilePosition.y + 1)) {

                    facing = Constants.DIRECTION_DOWN;
                    sprite.setFrame(Constants.DIRECTION_DOWN);
                    Gamestate.theMap.moveActorToTile(this, tilePosition.x, tilePosition.y, tilePosition.x, ++tilePosition.y);
                }
            break;

            case Constants.DIRECTION_RIGHT:
                if (canMoveTo(tilePosition.x + 1, tilePosition.y)) {
                    facing = Constants.DIRECTION_RIGHT;
                    sprite.setFrame(Constants.DIRECTION_RIGHT);
                    Gamestate.theMap.moveActorToTile(this, tilePosition.x, tilePosition.y, ++tilePosition.x, tilePosition.y);
                }
            break;
        }
    }

    public boolean isHero() {
        return this instanceof Hero;
    }

    public boolean isMonster() {
        return this instanceof Monster;
    }

    public boolean isObstacle() {
        return this instanceof Obstacle;
    }

    public void rotateLeft() {
        facing = (facing + 1) % 4;
    }

    public void rotateRight() {
        if (facing == 0) {
            facing = 3;
        }
        else {
            facing = (facing - 1);
        }
    }

    public void aboutFace() {
        facing = (facing + 2) % 4;
    }

    public Sprite getSprite() {
        return sprite;
    }

    public int getFacing() {
        return facing;
    }

    public void setSprite(Sprite sprite) {
        this.sprite = sprite;
    }

    public void setFacing(int facing) {
        this.facing = facing;
        sprite.setFrame(facing);
    }

    public Point2d getTilePosition() {
        return tilePosition;
    }

    public void setTilePosition(Point2d position) {
        this.tilePosition = position;
    }

    public void setTilePosition(int x, int y) {
        this.tilePosition = new Point2d(x, y);
    }

    public int getHP() {
        return HP;
    }

    public void setHP(int HP) {
        this.HP = HP;
    }

    public int getMaxHP() {
        return MaxHP;
    }

    public void setMaxHP(int MaxHP) {
        this.MaxHP = MaxHP;
    }

    /**
     * @return the spriteFileName
     */
    public String getSpriteFileName() {
        return spriteFileName;
    }

    public String toString()
    {
        return "HP: "+this.HP+"/"+this.MaxHP+"\nLocation: "+ tilePosition.toString()+"\n";
    }

    /**
     * @param spriteFileName the spriteFileName to set
     */
    public void setSpriteFileName(String spriteFileName) {
        this.spriteFileName = spriteFileName;
    }
}
